//customized Panel used to display debugging or miscelanious messages
// messages are stored to an Editor Pane that can be scrolled
//  Editor Pane will be setup to support full html capabilities
// new messages should append to the bottom and force the scrollbar to the bottom
//  to ensure the newest messages are visible
// editor will be held inside a Scroll Pane to allow scrolling capabilities

//import only what we need
import javax.swing.JPanel;
import javax.swing.JEditorPane;
import javax.swing.JScrollPane;
import java.awt.Font;
import java.awt.Color;
import java.awt.Rectangle;
import java.awt.GridLayout;
import java.util.ArrayList;

public class ConsoleLayer extends JPanel {
	
	
	//declare some class objects
	private JEditorPane consolebody;
	private JScrollPane consoleholder;
	private ArrayList<String> messages;
	
	//our constructor
	public ConsoleLayer(Rectangle bounds) {
		
		//call ancestor
		super();
		
		//initialize our message list
		this.messages = new ArrayList<String>();
		
		//initialize the Editor Pane to prepare for HTML formatted text
		this.consolebody = new JEditorPane();
		this.consolebody.setContentType("text/html");
		this.consolebody.setEditable(false);
		// add an initial message to the console
		this.appendMessage("<p style=\"font-family:courier new; color:red; font-size:20px\">***Checkers3D Console Output***</p><br>");
		//this.consolebody.setForeground(Color.WHITE);
		//this.consolebody.setBackground(new Color(0,0,0,120));
		
		//initialize the Scroll Pane to hold the editor and always have scroll bars
		this.consoleholder = new JScrollPane(this.consolebody, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
		
		//set properties for this layer
		this.setLayout(new GridLayout(1,1));
		//this.setBackground(new Color(0,0,0,120));
		this.setVisible(true);
		this.setOpaque(true);
		this.add(this.consoleholder);
		if (bounds != null){
			this.setBounds(bounds);
		}else{
			System.out.println("CONSOLELAYER: bounds were null!");
		}
		
	}
	
	//hidden convenience method to fixup any missing or extra <html> tags
	// will ensure the console text starts with openning html tag
	// will remove openning and closing html tags found that are in the center of console text
	// will ensure the console text ends with closing html tag
	private String validateTags(String htmlbody) {
		
		//get console text
		String bodytext = new String(htmlbody);
		//make a lowercase copy
		String bodylower = bodytext.toLowerCase();
		//check openning tags
		boolean openning = false;
		opens: for (int index=-1; index>=0 && index<=bodylower.length(); index = bodylower.indexOf("<html>", index+1)){
			if (index == 0){
				//first openning is in the correct position
				openning = true;
			}else if (index == -1){
				//no opennings left
				break opens;
			}else{
				//remove the extra openning
				bodytext = bodytext.substring(0, index) + bodytext.substring(index+6,bodytext.length());
				//update the lowercase copy
				bodylower = bodytext.toLowerCase();
			}
		}
		if (!openning){
			//add an openning
			bodytext = "<html>" + bodytext;
		}
		//make a lowercase copy
		bodylower = bodytext.toLowerCase();
		//check closing tags
		boolean closing = false;
		closes: for (int index=-1; index>=0 && index<=bodylower.length(); index = bodylower.indexOf("</html>", index+1)){
			if (index == bodylower.length()-7){
				//last closing is in the correct position
				closing = true;
			}else if (index == -1){
				//no closings left
				break closes;
			}else{
				//remove the extra openning
				bodytext = bodytext.substring(0, index) + bodytext.substring(index+7,bodytext.length());
				//update the lowercase copy
				bodylower = bodytext.toLowerCase();
			}
		}
		if (!closing){
			//add an closing
			bodytext = bodytext + "</html>";
		}
		//update changed body text
		return bodytext;
		
	}
	
	//method to append the specified message to the end of the current messages
	public void appendMessage(String message) {
		
		//System.out.println("$1ConsoleLayer: appending message = " + message);
		//add the new text to the list of messages
		this.messages.add(message);
		//combine all the existing messages
		String msgs = "";
		for (int i=0; i<messages.size(); ++i){
			msgs = msgs + messages.get(i);
		}
		//reset the console document
		this.consolebody.setDocument(this.consolebody.getEditorKit().createDefaultDocument());
		//validate the surrounding html tags for the combined messages
		msgs = this.validateTags(msgs);
		//add the new text
		this.consolebody.setText(msgs);
		//move to the bottom of the document
		this.consolebody.setCaretPosition(this.consolebody.getDocument().getLength());
		//this.validate();
		//this.repaint();
		//System.out.println("$1ConsoleLayer: body text -->\n" + this.consolebody.getText() + "\n");
		
	}
	
}